#include "generate_statement.h"

string generateStatement(ParseTree::Name ns, ParseTree::Statement &stat)
{
    return generateStatement(false, ns, stat);
}

// freeBlockNS should be true when a possible block is part of of the container namespace, e.g. a function.
string generateStatement(bool freeBlockNS, ParseTree::Name ns, ParseTree::Statement &stat)
{
    string c = "";
    if (stat.statementType == ParseTree::Statement::Block)
    {
        c += "{";
        ParseTree::Name name = ns;
        if (!freeBlockNS)
        {
            name.push_back(ParseTree::Identifier(stat.internalBlockReference));
        }
        for (unsigned int i = 0; i < stat.block.size(); i++)
        {
            c += generateStatement(name, stat.block[i]);
        }
        
        c += freeVars[name] + "}";
        freeVars[name] = "";
    } else if (stat.statementType == ParseTree::Statement::Expression)
    {
        c += generateStatementExpression(ns, *stat.expr);
    } else if (stat.statementType == ParseTree::Statement::Declaration)
    {
        c += generateDeclaration(ns, *stat.decl);
    } else if (stat.statementType == ParseTree::Statement::Return)
    {
        ParseTree::Type returnType = symbolTable[functionStack.back()].type;
        c += "return " + generateExpression(ns, *stat.returnexpr, returnType) + ";\n";
    }
    
    return c;
}

string generateStatementExpression(ParseTree::Name ns, ParseTree::StatementExpression &se)
{   
    //TODO void type
    ParseTree::Type voidType;
    voidType.typeType = ParseTree::Type::PrimitiveType;
    voidType.primitiveType = ParseTree::Type::Int;
    string c = "";
    if (se.seType == ParseTree::StatementExpression::StatDesignator)
    {
        c += generateDesignator(ns, *se.designator, voidType);//+ generateActPars(ns, se.params);
    }
    
    if (se.seType == ParseTree::StatementExpression::StatExpression)
    {
        c += generateExpression(ns, *se.expression, voidType);
    }
    
    return c + ";\n";
}

